# encoding:utf-8
# 自动部署到jenkins

import os, time, shutil, requests, json
from xml.etree import ElementTree


class config:
    # 主分支svn地址
    url_svn_main_code = 'https://db.winjoinit.com:8443/svn/Dev/project/泛糖科技网络货运平台/1.web/0.BackgroundManagementSystem'
    # 项目svn地址
    url_svn_code = 'https://db.winjoinit.com:8443/svn/Dev/project/泛糖科技网络货运平台/1.web/alpha'
    # 发布svn地址
    url_svn_deploy = 'https://db.winjoinit.com:8443/svn/Dev/project/泛糖科技网络货运平台/升级包/1.web/0.BackgroundManagementSystem'
    # 本地svn部署路径
    local_deploy_repo = 'F:/Repositories/FTKJWLHYPT/front/alpha/svn'
    # jenkins 用户名
    jenkins_username = 'front'
    # jenkins 密码
    jenkins_password = 'front'
    # 本地代码路径
    local_repo = 'F:/Repositories/FTKJWLHYPT/front/alpha/code'
    # 项目名称
    project_name = 'FTKJWLHYPT'
    # jenkins build url
    url_jenkins_build = 'http://192.168.1.126:8080/job/front-end-泛糖科技网络货运平台/build?delay=0sec'
    # jenkins state url
    url_jenkins_state = 'http://192.168.1.126:8080/job/front-end-泛糖科技网络货运平台/lastBuild/api/json?pretty=true'
    # jenkins token
    url_jenkins_token = 'http://192.168.1.126:8080/crumbIssuer/api/xml'


class doDeploy:

    config = None

    token = ''

    token_name = ''

    def __init__(self, config):
        config = config

    def refuse_repo(self):
        """
        更新代码
        """
        if config is None:
            print('请指定配置文件')
            exit(1)
        if not os.path.exists(config.local_repo):
            os.makedirs(config.local_repo)
        os.chdir(config.local_repo)
        if len(os.listdir(config.local_repo)) == 0:
            # 创建本地仓库
            os.system('svn checkout ' + config.url_svn_code + ' ' +
                      config.local_repo)
        else:
            # 更新代码
            os.system('svn update ' + config.local_repo)
        # 分支合并
        os.system('svn merge ' + config.url_svn_main_code + ' ' +
                  config.local_repo)
        os.system('svn commit -m auto')

    def tarCode(self):
        """
        目标文件构建
        """
        os.chdir(config.local_repo)
        if len(os.listdir(config.local_repo)) == 0:
            print('拉取代码失败，检查路径')
            exit(1)
        os.system('yarn install')
        os.system('yarn build')

    def initLocalDeployRepo(self):
        if not os.path.exists(config.local_deploy_repo):
            os.mkdir(config.local_deploy_repo)
        os.chdir(config.local_deploy_repo)
        if len(os.listdir(config.local_deploy_repo)) == 0:
            print('svn co --depth=empty ' + config.url_svn_deploy + ' ' +
                  config.local_deploy_repo)
            os.system('svn co --depth=empty ' + config.url_svn_deploy + ' ' +
                      config.local_deploy_repo)
        else:
            os.system('svn update ' + config.local_deploy_repo)

    def upload(self):
        """
        文件上传
        """
        now = time.strftime("%Y%m%d", time.localtime())
        path = config.local_deploy_repo + '/' + now
        if os.path.exists(path):
            os.system('svn up')
            for root, dirs, files in os.walk(path, topdown=False):
                for name in files:
                    os.system('svn del ' + os.path.join(root, name))
                    # os.remove(os.path.join(root, name))
                for name in dirs:
                    os.system('svn del ' + os.path.join(root, name))
                    # os.rmdir(os.path.join(root, name))
        os.system('svn commit -m auto')
        if not os.path.exists(path):
            os.makedirs(path)
        for root, dirs, files in os.walk(config.local_repo + '/dist/'):
            for name in files:
                o = os.path.join(root, name)
                n = os.path.join(path,
                                 o.replace(config.local_repo + '/dist/', ''))
                dir = n.replace(name, '')
                if not os.path.exists(dir):
                    os.makedirs(dir)
                shutil.copy(o, n)
        os.chdir(config.local_deploy_repo)
        content = os.popen('svn st -q').read().strip()
        contents = content.split('/n')
        # for con in contents:
        #     if con.find('!') != -1:
        #         del_path = con.replace('!', '').strip()
        #         os.system('svn del ' + del_path)
        os.system('svn add . --force --depth infinity')
        os.system('svn commit -m auto --depth infinity')

    def build(self):
        """
        jenkins build
        """
        # 获取token
        resp = requests.get(url=config.url_jenkins_token,
                            auth=(config.jenkins_username,
                                  config.jenkins_password))
        if not resp.status_code == 200:
            print('请求失败')
            print(resp.reason)
            exit(1)
        tree = ElementTree.fromstring(resp.text)
        self.token_name = tree.find('crumbRequestField').text
        self.token = tree.find('crumb').text
        requests.packages.urllib3.disable_warnings()
        param = time.strftime('%Y%m%d', time.localtime())
        data = {
            'name': 'DATE',
            'value': param,
            'statusCode': 303,
            'redirectTo': '.',
            self.token_name: self.token,
            'json': '{"parameter": {"name": "DATE", "value": "' + str(param) +
            '"}, "statusCode": "303", "redirectTo": "."}',
            'Submit': 'Build'
        }
        resp = requests.post(config.url_jenkins_build,
                             data=data,
                             headers={self.token_name: self.token},
                             auth=(config.jenkins_username,
                                   config.jenkins_password),
                             timeout=10)
        if not resp.status_code == 200:
            print('请求失败')
            print(resp.reason)
            exit(1)

    def check_state(self):
        max = 60
        i = 0
        while i < max:
            resp = requests.get(config.url_jenkins_state,
                                headers={self.token_name: self.token},
                                auth=(config.jenkins_username,
                                      config.jenkins_password),
                                timeout=10)
            if not resp.status_code == 200:
                print('请求失败')
                print(resp)
                exit(1)
            obj = json.loads(resp.text)
            if obj['building']:
                i = i + 1
                print('wait building >>> ' + str(3 * i) + 's')
                time.sleep(3)
            else:
                if not obj['result'] == 'SUCCESS':
                    print('发布失败')
                    exit(1)
                else:
                    return
        else:
            print('构建失败')
            exit(1)


doDeploy = doDeploy(config=config())

doDeploy.refuse_repo()
doDeploy.tarCode()
doDeploy.initLocalDeployRepo()
doDeploy.upload()
doDeploy.build()
doDeploy.check_state()

print('success')
exit(0)
